package cn.kwq.project_manger.chat;

import cn.kwq.project_manger.dtoUtils.ChatUtils;
import cn.kwq.project_manger.pojo.QUser;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: kwq
 * @Date: 2022/12/31/23:19
 * @Description:
 */
@Service
@Slf4j
public class ChatServiceImpl {
    @Autowired
    ChatRepository chatRepository;
    @Autowired
    ChatMsgRepository chatMsgRepository;
    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @Autowired
    ChatUtils chatUtils;

    @Transactional(rollbackFor = Exception.class)
    public void sendMsg(Long from, Long to,String msg){
        QChat chat=QChat.chat;
        //查看是否已经存在对话
        Long chatId = jpaQueryFactory.select(chat.chatId)
                .from(chat)
                .where((chat.fromId.eq(from).and(chat.toId.eq(to)))
                        .or(chat.fromId.eq(to).and(chat.toId.eq(from))))
                .fetchOne();
        //不存在就
        if(chatId == null) {
            Chat save = chatRepository.save(Chat.builder()
                    .fromId(from)
                    .toId(to)
                    .build());
            chatId = save.getChatId();

        }
        //存在就导入记录
        Optional.ofNullable(chatId).ifPresent(id ->
                chatMsgRepository.save(
                        ChatMsg.builder()
                                .chatId(id)
                                .createTime(new Date())
                                .fromId(from)
                                .toId(to)
                                .msg(msg)
                                .build()));

        if(chatId == null){
            log.error("持久化错误");
            throw new RuntimeException("持久化错误");
        }
        log.info("持久化消息完成");

    }


    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public List<ChatDto> findAllChatMsgList(Long from, Long to,Integer pageSize, Integer pageNum){
        QChatMsg cs=QChatMsg.chatMsg;
        QChat chat=QChat.chat;
        List<ChatDto> fetch = jpaQueryFactory
                .select(
                        Projections.bean(
                        ChatDto.class,
                        cs.chatId,
                        cs.createdDate,
                        cs.msg,
                        cs.fromId,
                        cs.toId
                ))
                .from(cs)
                .leftJoin(chat).on(chat.chatId.eq(cs.chatId))
                //条件
                .where((chat.fromId.eq(from).and(chat.toId.eq(to)))
                        .or(chat.fromId.eq(to).and(chat.toId.eq(from))))
                //排序
                .orderBy(cs.createdDate.desc())
                //分页
                .offset((long) (pageNum - 1) * pageSize)
                .limit(pageSize)
                .fetch();

        Long total = jpaQueryFactory
                .select(cs.count())
                .from(cs)
                .leftJoin(chat).on(chat.chatId.eq(cs.chatId))
                .where((chat.fromId.eq(from).and(chat.toId.eq(to)))
                        .or(chat.fromId.eq(to).and(chat.toId.eq(from))))
                .fetchOne();


        Optional.ofNullable(fetch).ifPresent(list -> {
            for (ChatDto c: list){
                if (c.getFromId().equals(from) && c.getToId().equals(to)){
                    c.setIsRight(true);
                    c.setTotal(total);
                } else if (c.getFromId().equals(to) && c.getToId().equals(from)){
                    c.setIsRight(false);
                    c.setTotal(total);
                }else {
                    throw new RuntimeException("查询结果为错误");
                }
            }
        });
        //反转集合
        Collections.reverse(fetch);
        return fetch;
    }

    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public List<ChatListDto> findAllChatMsgList(Long from){
        QChatMsg cs=QChatMsg.chatMsg;
        QChat chat=QChat.chat;
        List<Chat> fetch = jpaQueryFactory
                .select(
                        Projections.bean(
                                Chat.class,
                                cs.chatId,
                                cs.fromId,
                                cs.toId
                        ))
                .from(cs)
                .leftJoin(chat).on(chat.chatId.eq(cs.chatId))
                .where((chat.fromId.eq(from)
                        .or(chat.toId.eq(from))))
                .orderBy(chat.chatId.asc())
                .fetch();

       return fetch.stream()
               .map(c-> ChatListDto.builder()
                .fromId(c.getFromId())
                .toId(c.getToId())
                .userName(chatUtils.getUserNameByFromId(c.getFromId(),c.getToId(),from))
                .lastMsg(chatUtils.getLastMsg(c.getFromId(),c.getToId()))
                .build())
               .distinct()
               .filter(item->item.getFromId().equals(from))
               .collect(Collectors.toList());
    }




}
